/*                    BioJava development code
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  If you do not have a copy,
 * see:
 *
 *      http://www.gnu.org/copyleft/lesser.html
 * Copyright for this code is held jointly by the individual
 * authors.  These should be listed in @author doc comments.
 *
 * For more information on the BioJava project and its aims,
 * or to join the biojava-l mailing list, visit the home page
 * at:
 *
 *      http://www.biojava.org/
 *
 * Created on 08.10.2007
 * @author Asia Grzibovska
 *
 */
package examples;

import java.util.*;
import java.io.*;
import java.net.*;

import uk.ac.sanger.FeatureBean;
import uk.ac.sanger.MyPrettyXMLWriter;


/** a class that shows how to send data to writeback.
 * example usage:

 * @author Asia Grzibovska
 * @since 08 oct 2007
 */
public class GetWriteback {

	public static final String CREATE_CMD ="1";
	public static final String MODIFY_CMD ="2";
	public static final String DELETE_CMD ="3";
	
    //URL of writeback server, port 8088 or 8080
	public static final String
			WRITEBACK_SERVER = "http://localhost:8088/writebackServlet/writebackDatabase";

	public static void main(String[] args) {
		try {

			GetWriteback writeback = new GetWriteback();

			//construct array of FeatureBeans
			FeatureBean[] f= writeback.initializeBeans();

			if (f.length > 0){
				for (int i = 0; i < f.length; i++) {
					FeatureBean feature = f[i];
					//POST feature to the Writeback server
					//get result "OK" or error description
					String result=writeback.writebackPost(feature);
					System.out.println("result " + result);
				}
			}    
			else System.out.println("Error! No data set!");

		} catch ( Exception e) {
			e.printStackTrace();}      
	}

	// This method initializes and returns array of beans. 
	// In this example we used 1 feature only.
	public FeatureBean[] initializeBeans()  {
		//make lit of features
		List features;
		features = new ArrayList();	

		try{	
			//set of attributes for one feature
			FeatureBean f ;	
			f = new FeatureBean();
			
			Random generator = new Random();
			//feature id, REQUIRED
			f.setFeatureid("new_feature" + generator.nextInt(100));
			//feature type, REQUIRED
			f.setFeaturetype("type_test");
			//feature method, REQUIRED
			f.setMethod("method_test");
			//feature segment, REQUIRED
			f.setSegment("segment_test");
			//feature start, OPTIONAL
			f.setStart("1");
			//feature end, OPTIONAL
			f.setEnd("2");
			//feature strand, REQUIRED
			f.setStrand("+");
			//feature phase, REQUIRED
			f.setPhase(".");
			//feature score, OPTIONAL
			f.setScore("1");
			//link with additional info about feature, OPTIONAL
			f.setLinks("www.link.com");
			//plain text note, OPTIONAL
			f.setNotes("test note");
			//group to which feature belong, OPTIONAL
			f.setGroups("group");
			//commitment message, OPTIONAL
			f.setCommitMsg("added a new feature");
			//user id from Open-Id identification system, OPTIONAL
			f.setUser("user.myopenid.com");
			//coordinate system URI, VERY IMPORTANT!
			f.setSystem_uri("CS_DS26");

			features.add(f);
		}	

		catch (Exception e) {
			e.printStackTrace();
		}
		//return feature as FeatureBean
		return (FeatureBean[]) features.toArray(new FeatureBean[features.size()]);
	}

	// In this method feature data is sent  
	// to the writeback server.
	// Input parameters : @FeatureBean, initialized
	public String writebackPost(FeatureBean f ){
		String response = "";
		try {
			// Send data
			URL url = new URL(WRITEBACK_SERVER);
			
			// Establish connection
			URLConnection conn = url.openConnection();
			conn.setDoOutput(true);
			
			// Initialize OutputStream
			OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
            
			// Convert FeatureBean into XML format
			response=convertFeaturesXML(out, conn, f, CREATE_CMD);

			// Close streams
			out.flush();
			out.close();

		} catch (Exception e) {
			//e.printStackTrace();
		}
		//return response
		return response;
	}
	
	// In this method we construct XML file, 
	// and send via HTTP to the writeback server
	// Input parameters : @OutputStreamWriter,
	// @URLconnection to the server, 
	// @FeatureBean that is initialised and contains data
	// @mode can be CREATE_CMD or MODIFY_CMD or DELETE_CMD
	public String convertFeaturesXML(OutputStreamWriter out,
			URLConnection connection, FeatureBean f, 
			String mode)
	throws IOException {
		try {
			//initialize returned value
			String response ="";

			//send data in a stream
			PrintWriter pw = new PrintWriter(out);
			MyPrettyXMLWriter xw = new MyPrettyXMLWriter(pw);
            
			//construct XML
			xw.openTag("WRITEBACK");
			xw.attribute("xmlns", "http://biodas.org/documents/das2");
			xw.attribute("xml:base", "http://example.com/das2/dasypus/April2006/");
			xw.openTag("MESSAGE");
			xw.print(f.getCommitMsg()); // commit message
			xw.closeTag("MESSAGE");
			if (mode.equals(MODIFY_CMD)) {
				xw.openTag("UPDATES");
				xw.openTag("UPDATE");
				xw.attribute("uri", f.getFeatureid());
				xw.closeTag("UPDATE");
				xw.closeTag("UPDATES");
			}
			if (mode.equals(DELETE_CMD)) {
				xw.openTag("DELETES");
				xw.openTag("DELETE");
				xw.attribute("uri", f.getFeatureid());
				xw.closeTag("DELETE");
				xw.closeTag("DELETES");
				xw.openTag("FEATURE ");
			} else {
				xw.openTag("FEATURE ");
				xw.attribute("featureid", f.getFeatureid());
				xw.attribute("featuretype", f.getFeaturetype());
				xw.attribute("method", f.getMethod());
				xw.openTag("LOC");
				xw.attribute("segment", f.getSegment());
				xw.attribute("range", f.getStart() + ":" + f.getEnd() + ":"
						+ f.getStrand());
				xw.closeTag("LOC");
				xw.openTag("PROPERTY");
				xw.attribute("phase", f.getPhase());
				xw.closeTag("PROPERTY");
				xw.openTag("PROPERTY");
				xw.attribute("score", f.getScore());
				xw.closeTag("PROPERTY");
				xw.openTag("PROPERTY");
				xw.attribute("link", f.getLinks());
				xw.closeTag("PROPERTY");
				xw.openTag("PROPERTY");
				xw.attribute("groups", f.getGroups());
				xw.closeTag("PROPERTY");
			}
			xw.openTag("PROPERTY");
			xw.attribute("note", f.getNotes());
			xw.closeTag("PROPERTY");
			xw.openTag("PROPERTY");
			xw.attribute("user", f.getUser());
			xw.closeTag("PROPERTY");
			xw.openTag("PROPERTY");
			xw.attribute("system_uri", f.getSystem_uri());
			xw.closeTag("PROPERTY");

			xw.closeTag("FEATURE");

			xw.closeTag("WRITEBACK");
			xw.close();
			out.close();

			//Get the response, that is either "OK"
			//or error message description
			BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
			String line;
			while ((line = rd.readLine()) != null) {
				response=line;
				//System.out.println("response  : "+line);
			}
			//close streams
			out.close();
			rd.close();

			return response;

		} catch (Exception e) {
			e.printStackTrace();
			return "error, something went wrong while sebding XML";
		}
	}
}
